package com.glodon.paas.account.dao.redis;

import static org.junit.Assert.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.auth.BasicUserPrincipal;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.DefaultAuthorizationRequest;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import redis.clients.jedis.JedisPool;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {
		"classpath:spring-config-test.xml",
		"classpath:paas-account-dao-mysql.xml"		
		})
public class RedisTokenStoreIT {

	@Autowired
	RedisTokenStore tokenStore;
	
    private DefaultOAuth2AccessToken oauth2token; 
    private DefaultOAuth2RefreshToken refreshToken;    
    private OAuth2Authentication authentication;
    
	@Before
	public void setUp() throws Exception {
		Map<String, String> authorizationParameters = new HashMap<String, String>();
		//Authentication auth = //new BasicUserPrincipal("oauth2User");
		authentication= new OAuth2Authentication(new DefaultAuthorizationRequest(authorizationParameters), null);	
		
		oauth2token = new DefaultOAuth2AccessToken("oauth2tokenValue"); 
		refreshToken = new DefaultOAuth2RefreshToken("oauth2RefreshToken");
		oauth2token.setRefreshToken(refreshToken);		
		tokenStore.storeAccessToken(oauth2token, authentication);
		
		tokenStore.storeRefreshToken(refreshToken, authentication);
	}

	@After
	public void tearDown() throws Exception {
		tokenStore.removeRefreshToken(refreshToken);
		tokenStore.removeAccessToken(oauth2token);
	}

	@Test
	public void ReadAuthenticationOAuth2AccessToken() {
		OAuth2Authentication a = tokenStore.readAuthentication(oauth2token);
		assertNotNull(a);
	}

	@Test
	public void ReadAuthenticationString() {
		OAuth2Authentication a = tokenStore.readAuthentication(oauth2token.getValue());
		assertNotNull(a);
	}

	@Test
	public void StoreAccessToken() {
		tokenStore.storeAccessToken(oauth2token, authentication);
	}

	@Test
	public void ReadAccessToken() {
		OAuth2AccessToken t = tokenStore.readAccessToken(oauth2token.getValue());
		assertNotNull(t);
		//assertThat(t.getValue(),is(key));
		//assertTrue(t.isAccessToken());
	}

	@Test
	public void RemoveAccessToken() {
		tokenStore.removeAccessToken(oauth2token);
		OAuth2AccessToken t = tokenStore.readAccessToken(oauth2token.getValue());		
		assertNull(t);
		OAuth2Authentication a = tokenStore.readAuthentication(oauth2token.getValue());
		assertNull(a);	
		
		Collection<OAuth2AccessToken> c = tokenStore.findTokensByClientId(authentication.getAuthorizationRequest().getClientId());
		assertTrue(c.isEmpty());
		
		//TODO:findtokenbyname
		
	}

	@Test
	public void StoreRefreshToken() {
		tokenStore.storeRefreshToken(refreshToken, authentication);
	}

	@Test
	public void ReadRefreshToken() {
		OAuth2RefreshToken t = tokenStore.readRefreshToken(oauth2token.getRefreshToken().getValue());
		assertNotNull(t);
	}

	@Test
	public void ReadAuthenticationForRefreshToken() {
		OAuth2Authentication a = tokenStore.readAuthenticationForRefreshToken(refreshToken);
		assertNotNull(a);
	}

	@Test
	public void RemoveRefreshToken() {
		tokenStore.removeRefreshToken(refreshToken);
		OAuth2RefreshToken t = tokenStore.readRefreshToken(oauth2token.getRefreshToken().getValue());
		assertNull(t);
		
		OAuth2Authentication a = tokenStore.readAuthenticationForRefreshToken(refreshToken);
		assertNull(a);
	}

	@Test
	public void RemoveAccessTokenUsingRefreshToken() {
		tokenStore.removeAccessTokenUsingRefreshToken(refreshToken);
		OAuth2AccessToken t = tokenStore.getAccessTokenFromRefreshToken(refreshToken);
		assertNull(t);
	}

	@Test
	public void GetAccessToken() {
		OAuth2AccessToken t = tokenStore.getAccessToken(authentication);
		assertNotNull(t);
	}

	@Test
	public void FindTokensByUserName() {
		///fail("Not yet implemented");
	}

	@Test
	public void FindTokensByClientId() {
		Collection<OAuth2AccessToken> c = tokenStore.findTokensByClientId(authentication.getAuthorizationRequest().getClientId());
		assertTrue(!c.isEmpty());
	}

}
